home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 11 / AMUG BBS in a Box Volume XI (April 1994) (MacWizards).iso / Files / System7 tools / Frontier / DocServer 1.1b5.sit / DocServer 1.1b5 / UserTalk Source Text / UserTalk Source Text
Encoding:
Text File  |  1992-04-16  |  36.9 KB  |  661 lines  |  [TEXT/DOCS]

  1. Verb    +
  2. Syntax    expression1 + expression2
  3. Action    The arithmetic addition operator yields the sum of the values of expression1 and expression2.
  4. Examples    1 + 1
  5.     » 2
  6. UserTalk can add one and one with great facility!
  7.  
  8. "one" + "one"
  9.     » oneone
  10. The addition operator can be used to concatenate strings.
  11.  
  12. 3 + "k bytes needed."
  13.     « 3k bytes needed.
  14. Notes    UserTalk employs automatic type coercion when evaluating arithmetic and comparative operations; the two expressions need not be of the same type to be added together. Generally, the resulting type — which determines the method of addition — is the more complex type, the one that can most readily represent both values.
  15. See Also    –
  16. *
  17. /
  18. %
  19.  
  20. Verb    -
  21. Syntax    expression1 – expression2
  22. Action    The arithmetic subtraction operator yields the difference of the values of expression1 and expression2.
  23. Examples    3 – 0.5
  24.     » 2.5
  25. The number 3 is “promoted” to a double, the type of 0.5, in order to perform the subtraction.
  26.  
  27. "workfile.backup" – ".backup"
  28.     » workfile
  29. The subtraction operator works with strings; the result is the removal of the first occurrence of the second string from the first string.
  30.  
  31. "abc" – "def"
  32.     « abc
  33. The second string does not appear in the first, so nothing is removed.
  34. Notes    UserTalk employs automatic type coercion when evaluating arithmetic and comparative operations; the two expressions need not be of the same type to be subtracted. Generally, the resulting type — which determines the method of subtraction — is the more complex type, the one that can most readily represent both values.
  35. The minus operator can also appear before a single operand to indicate arithmetic negation.
  36. See Also    +
  37. *
  38. /
  39. %
  40.  
  41. Verb    *
  42. Syntax    expression1 * expression2
  43. Action    The arithmetic multiplication operator yields the product of the values of expression1 and expression2.
  44. Examples    3 * 0.5
  45.     » 1.5
  46. The number 3 is “promoted” to a double, the type of 0.5, in order to perform the multiplication.
  47.  
  48. "abc" * "def"
  49.     «
  50. This statement generates an error; only numbers can be used as multiplication operands.
  51. Notes    UserTalk employs automatic type coercion when evaluating arithmetic and comparative operations; the two expressions need not be of the same type to be multiplied together. Generally, the resulting type is the more complex type, the one that can most readily represent both values.
  52. Only numeric-compatible types — short, long, single, double, date, etc. — can be multiplied.
  53. See Also    +
  54. /
  55. %
  56.  
  57. Verb    /
  58. Syntax    expression1 / expression2
  59. Action    The arithmetic division operator yields the result of dividing the value of expression1 by the value of expression2.
  60. Examples    10 / 3
  61.     » 3
  62. The result of integer division is truncated.
  63.  
  64. 10 / 3.0
  65.     » 3.3333
  66. The number 10 is “promoted” to a double, the type of 3.0, in order to perform the division.
  67.  
  68. long (clock.now () / 3600)
  69.     » 770199
  70. This expression yields the number of hours that have passed since midnight, Jan 1, 1904.
  71. Notes    UserTalk employs automatic type coercion when evaluating arithmetic and comparative operations; the two expressions or the division operation need not be of the same type. Generally, the resulting type is the more complex type, the one that can most readily represent both values.
  72. Only numeric-compatible types — short, long, single, double, date, etc. — can be divided by one another.
  73. See Also    +
  74. *
  75. %
  76.  
  77. Verb    =
  78. Syntax    identifier = expression
  79. Action    Evaluates expression and assigns the resulting value to identifier.
  80. Examples    local (x);
  81. x = 3 * 4
  82.     » 12
  83. The assignment statement causes the value of the expression “3 * 4” to be stored in the local variable “x”.
  84.  
  85. scratchpad.when = clock.now ()
  86.     » 11/11/91; 7:36 PM
  87. In this case the expression “clock.now ()” yielded a date value, which was then assigned to the cell named “when” in the table named “scratchpad.” (The “when” cell need not have already existed.)
  88. Notes    The identifier need not specify an existing database cell; the assignment statement will create an item with the given name in the specified table. If no table is specified, a local variable is implicitly declared in the current scope level. That is, an assignment to an undefined identifier behaves as if it were a local declaration. While this can be a timesaver, it is generally bad practice to count on this behavior; as a script becomes more complex, it quickly becomes easy to unintentionally modify a variable in an enclosing scope level.
  89. See Also    local
  90.  
  91. Verb    ==
  92. Syntax    expression1 == expression2
  93. expression1 equals expression2
  94. Action    The equality operator yields the boolean value true if the value of expression1 and the value of expression2 are the same.
  95. Examples    file.type ("myFile") equals 'TEXT'
  96.     » true
  97. This expression evaluates to true if file.type returns ‘TEXT’ as its result.
  98.  
  99. 27 == "27"
  100.     » true
  101. When coerced to be of the same type, the two representations of the number 27 are equal, and the result of the operation is true.
  102. Notes    There is no difference between the two forms, == and equals.
  103. UserTalk employs automatic type coercion when evaluating arithmetic and comparative operations; the two expressions need not be of the same type for their values to be “equal.”
  104. See Also    >
  105. <
  106. >=
  107. <=
  108.  
  109. Verb    ≠
  110. Syntax    expression1 ≠ expression2
  111. expression1 != expression2
  112. expression1 notequals expression2
  113. Action    The inequality operator yields the boolean value true if the value of expression1 and the value of expression2 are not the same.
  114. Examples    file.type ("myFile") ≠ 'TEXT'
  115.     » true
  116. This expression evaluates to true if file.type returns anything other than ‘TEXT’ as its result.
  117.  
  118. "27" notequals 27
  119.     » false
  120. When coerced to be of the same type, the two representations of the number 27 are equal, and the result of the operation is false.
  121. Notes    There is no difference between the three forms, !=, ≠ and notequals.
  122. UserTalk employs automatic type coercion when evaluating arithmetic and comparative operations; if the two expressions are of different types, it does not imply inequality.
  123. The ≠ symbol can be entered at the keyboard with Option–=.
  124. See Also    >
  125. <
  126. >=
  127. <=
  128. ==
  129.  
  130. Verb    <
  131. Syntax    expression1 < expression2
  132. expression1 lessthan expression2
  133. Action    This comparison operator yields the boolean value true if the value of expression1 is less (smaller) than the value of expression2.
  134. Examples    file.size ("myFile") < 1000000
  135.     » true
  136. This expression evaluates to true if the file contains less than one million characters.
  137.  
  138. "abd" < "azz"
  139.     » true
  140. Notes    There is no difference between the two forms, < and lessthan.
  141. String comparison is carried out according to the ASCII sequence; this yields alphabetical results, but lowercase characters sort after all uppercase characters. That is, “A” < “Z” < “a” < “z”.
  142. UserTalk employs automatic type coercion when evaluating arithmetic and comparative operations; the two expressions need not be of the same type to be compared.
  143. See Also    >
  144. >=
  145. <=
  146. ==
  147.  
  148. Verb    <=
  149. Syntax    expression1 <= expression2
  150. expression1 ≤ expression2
  151. Action    This comparison operator yields the boolean value true if the value of expression1 is less (smaller) than or equal to the value of expression2.
  152. Examples    file.size ("myFile") <= 1000000
  153.     » true
  154. This expression evaluates to true if the file contains one million or fewer characters.
  155.  
  156. "abc" ≤ "abc"
  157.     » true
  158. The result is true, because the two expressions are equal.
  159. Notes    There is no difference between the two forms, <= and ≤.
  160. String comparison is done according to the ASCII sequence. This yields alphabetical results. Lowercase characters sort after all uppercase characters, that is, “A” < “Z” < “a” < “z”.
  161. UserTalk employs automatic type coercion when evaluating arithmetic and comparative operations; the two expressions need not be of the same type to be compared.
  162. The ≤ symbol can be entered at the keyboard with Option–<
  163. See Also    >
  164. >=
  165. <
  166. ==
  167.  
  168. Verb    >
  169. Syntax    expression1 > expression2
  170. expression1 greaterthan expression2
  171. Action    This comparison operator yields the boolean value true if the value of expression1 is greater (larger) than the value of expression2.
  172. Examples    file.size ("myFile") > 1000000
  173.     » true
  174. This expression evaluates to true if file.size returns a value larger than one million.
  175.  
  176. "abdc" > "a"
  177.     » true
  178. Notes    There is no difference between the two forms, < and greaterthan.
  179. String comparison is carried out according to the ASCII sequence; this yields alphabetical results, but lowercase characters sort after all uppercase characters, that is, “A” < “Z” < “a” < “z”.
  180. UserTalk employs automatic type coercion when evaluating arithmetic and comparative operations; the two expressions need not be of the same type to be compared.
  181. See Also    <
  182. >=
  183. <=
  184. ==
  185.  
  186. Verb    >=
  187. Syntax    expression1 >= expression2
  188. expression1 ≥ expression2
  189. Action    This comparison operator yields the boolean value true if the value of expression1 is greater (larger) than or equal to the value of expression2.
  190. Examples    file.size ("myFile") >= 1000000
  191.     » true
  192. This expression evaluates to true if file.size returns a value larger than or equal to one million.
  193.  
  194. "abc" ≥ "abc"
  195.     » true
  196. The result is true, because the two expressions are equal. 
  197. Notes    There is no difference between the two forms, <= and ≤.
  198. String comparison is carried out according to the ASCII sequence. This yields alphabetical results. Lowercase characters sort after all uppercase characters, that is, “A” < “Z” < “a” < “z”.
  199. UserTalk employs automatic type coercion when evaluating arithmetic and comparative operations; the two expressions need not be of the same type to be compared.
  200. The ≥ symbol can be entered at the keyboard with Option–>
  201. See Also    >
  202. <
  203. <=
  204. ==
  205.  
  206. Verb    not
  207. Syntax    not expression
  208. !expression
  209. Action    The logical negation (boolean “not”) operator, yields the boolean value true if expression evaluates to false, or false if expression evaluates to true.
  210. Examples    not file.exists ("myFile")
  211. This expression evaluates to true if the file does not exist; if the file does exist, it evaluates to false.
  212. Notes    There is no difference between the two forms, ! and not.
  213. See Also    and   
  214. or
  215.  
  216. Verb    ()
  217. Syntax    identifier (expression1, ..., expressionN)
  218. Action    Invokes the script named by identifier, passing the values resulting from expression1 through expressionN as parameters. The number of parameter provided must match the number expected by the script, as defined in its “on” statement script header. The value returned by the script becomes the value of the script call expression.
  219. Examples    clock.now ()
  220.     » 11/11/91; 7:51 PM
  221. Here we’re calling the built-in verb clock.now; the result of the call is the value returned by the verb. Note that the parenthesis notation must be used to indicate that we are making a call to the verb, even though it takes no parameters.
  222.  
  223. on addThree (n1, n2, n3){
  224.     return (n1 + n2 + n3)};
  225. total = addThree (1, 2, 3)
  226.     » 6
  227. This example illustrates the correspondence between the parameter list provided when calling a script with the parameter declaration in the script’s defining “on” statement.
  228. Notes    Forgetting to provide an empty pair of parentheses when no parameters are required is a common scripting error — watch for it.
  229. See Also    on
  230.  
  231. Verb    ++
  232. Syntax    ++identifier
  233. identifier++
  234. Action    The increment operator adds the numeric value 1 to identifier. In the first case, where the increment operator appears before identifier, the value of the increment expression is the value of identifier after it is incremented. That is, the increment operation takes place first, and the result is used as the value of the expression. In the second case, where the increment operator appears after identifier, the value of the increment expression is the value of identifier before it is incremented; the increment operation takes place after the expression’s value has been determined.
  235. Examples    x = 3; ++x
  236.     » 4
  237. Since x is “pre-incremented,” its final value of 4 is the result of the expression.
  238.  
  239. x = 3; x++
  240.     » 3
  241. In this case, x is “post-incremented,” and the result of the expression is its value before 1 is added to it. Its value after the statement is executed is still 4.
  242. Notes    Any type that supports addition can be used with the increment operator.
  243. See Also    +
  244. ––
  245.  
  246. Verb    --
  247. Syntax    ––identifier
  248. identifier––
  249. Action    The decrement operator subtracts the numeric value 1 from identifier. In the first case, where the decrement operator appears before identifier, the value of the decrement expression is the value of identifier after it is decremented. That is, the decrement operation takes place first, and the result is used as the value of the expression. In the second case, where the decrement operator appears after identifier, the value of the decrement expression is the value of identifier before it is decremented; the decrement operation takes place after the expression’s value has been determined.
  250. Examples    x = 3; ––x
  251.     » 2
  252. Since x is “pre-decremented,” its final value of 2 is the result of the expression.
  253.  
  254. x = 3; x––
  255.     » 3
  256. In this case, x is “post-decremented,” and the result of the expression is its value before 1 is subtracted from it. Its value after the statement is executed is still 2.
  257. Notes    Any type that supports subtraction can be used with the decrement operator.
  258. See Also    –
  259. ++
  260.  
  261. Verb    and
  262. Syntax    expression1 and expression2
  263. expression1 && expression2
  264. Action    The logical conjunction (boolean “and”) operator, yields the boolean value true if both expression1 and expression2 evaluate to true, false otherwise.
  265. Examples    file.exists ("myFile") and (!file.exists ("myFile"))
  266.     » false
  267. This expression always evaluates to false, because it is impossible for both expressions to be true at the same time.
  268.  
  269. file.exists ("myFile") and (file.type ("myFile") == 'TEXT')
  270.     » true
  271. This expression evaluates to true if “myFile” exists and is a text file.
  272. Notes    There is no difference between the two forms, && and and.
  273. UserTalk employs “short-circuit” evaluation of boolean expressions. In other words, if expression1 of an and operation evaluates to false, expression2 will not be evaluated, since it can already be determined that the result of the operation will be false. In example #2 above, the call to file.type will never be made if file.exists returns false (i.e., the file doesn’t exist).
  274. See Also    or
  275. not
  276.  
  277. Verb    or
  278. Syntax    expression1 or expression2
  279. expression1 || expression2
  280. Action    The logical disjunction (boolean “or”) operator, yields the boolean value true if either expression1 or expression2 evaluates to true, false otherwise.
  281. Examples    file.exists ("myFile") or !file.exists ("myFile")
  282.     » true
  283. This expression always evaluates to true, because it is impossible for both expressions to be false at the same time.
  284.  
  285. file.isFolder ("myFile") or (file.type ("myFile") != 'TEXT')
  286.     » true
  287. This expression evaluates to true if “myFile” is a folder, or is not a text file.
  288. Notes    There is no difference between the two forms, || and or.
  289. UserTalk employs “short-circuit” evaluation of boolean expressions. That means that if expression1 of an or operation evaluates to true, expression2 will not be evaluated, since it can already be determined that the result of the operation will be true. So in example #2 above, the call to file.type will never be made if file.isFolder returns true.
  290. See Also    and
  291. not
  292.  
  293. Verb    .
  294. Syntax    identifier1 . identifier2
  295. identifier1 . [expression2]
  296. Action    Names an Object Database cell. The value of a “dotted-ID” expression is the value contained in the database cell.
  297. In the first form above, identifier1 refers to a database table, and identifier2 refers to an item in that table. In the second form, expression2 is evaluated, and the result is treated as a string and used to name the table item. In either case, the item itself need not already exist to be valid. In an assignment, for example, the assignment statement itself will create the named entry to store the value.
  298. Examples    scratchpad.x = 7
  299. Assigns the numeric value 7 to the item named “x” in the table named “scratchpad.” If “x” already exists, its previous value is replaced; it not, a new value is created.
  300.  
  301. examples.age
  302.     » 46
  303. Yields the value of the database cell named “age” in the “examples” table.
  304.  
  305. sizeOf (people.[user.initials].notepad)
  306.     » 65
  307. This example demonstrates the power of the bracket notation. First, the expression “user.initials” is evaluated. The resulting value is used to name an item in the “people” table, the one belonging to the current user. Finally, the item named “notepad” is referenced in the table specified by “people.[user.initials].” The result indicates that the outline contains 65 headings.
  308. Notes    As illustrated in the third example above, a dotted-ID pair can be used as the identifier for the table in another dotted-ID pair. The full database path to an item is a series of dotted-IDs, starting with the root table. (Though, for brevity, the “root” table itself can be — and often is — omitted.)
  309. See Also    @
  310. =
  311.  
  312. Verb    @
  313. Syntax    @identifier
  314. Action    Takes the address of identifier. The address can be used with the dereference operator (^) to refer back to the original object specified by identifier. Addresses provide a way to refer to Object Database cells rather than their contents. A script that takes the address of an object as a parameter can change the contents of that database location, while a script that takes an object’s value as a parameter works only with a copy of that value.
  315. Examples    name = "";
  316. if dialog.ask ("What's your name?", @name)
  317. {msg (name)}
  318. The built-in verb dialog.ask takes the address of a string as its second parameter. When passed the address of the local variable “name,” dialog.ask is able to change its value.
  319.  
  320. saying = "A bird in the hand is worth two in the bush";
  321. string.countWords (saying)
  322. In this case, the built-in verb string.countWords doesn’t need to be able to change the original string; it just wants to work with its value. Therefore, we don’t use the address operator.
  323. Notes    Strings that name database cells can be coerced to an address with the address global verb. As a result, the value of address (“system.verbs”) is equal to @system.verbs.
  324. See Also    ^
  325.  
  326. Verb    ^
  327. Syntax    expression^
  328. Action    This operator is referred to as the dereference operator. It evaluates expression and, interpreting the result as the address of an Object Database cell, yields the value of that cell.
  329. Examples    local (addr = @examples.age);
  330. x = addr^
  331.     » 46
  332. This simple example shows how the dereference operator extracts the value of the address, in this case the address of the “age” cell in the “examples” table.
  333.  
  334. on triple (addrN)
  335.    addrN^ = addrN^ * 3
  336. triple (@examples.age)
  337. Type this script into a script window. In this example, the local script “triple” multiplies by three the value whose address is passed to it. 
  338.  
  339. The example below demonstrates a more straightforward method of accomplishing the same thing, but it is interesting see how the @ and ^ operators work together here.
  340.     on triple (n)
  341.         return (n * 3)
  342.     examples.age = triple (examples.age)
  343.  
  344. Type this script into a script window:
  345.     typeOf (window.frontmost ()^) == tableType
  346.         » true
  347. Here, the value returned by window.frontmost — a string — is treated as a database address, and the type of the value at that address is compared to tableType. If the frontmost window contains a table, the result of the expression will be true.
  348. Notes    The technique shown in the second example above is generally advisable only when working with large pieces of data that reside in the database, such as binary values, in which case memory overhead may be reduced. Otherwise, the simpler approach of example #3 is preferable.
  349. See Also    @
  350.  
  351. Verb    %
  352. Syntax    expression1 % expression2
  353. Action    The arithmetic modulus operator yields the remainder when dividing the value of expression1 by the value of expression2.
  354. Examples    10 % 4
  355.     » 2
  356. Four goes two times into 10, leaving a remainder of two.
  357.  
  358. 10 % 4.0
  359.     »
  360. This statement generates an error; the modulus operator does not work on floating point values, since the result of floating point division is not truncated and thus has no remainder.
  361.  
  362. long (clock.now () % 3600)
  363.     » 2566
  364. This expression yields the number of seconds into the current hour we are right now.
  365. Notes    Only integral-compatible types — short, long, date, etc. — can be used in the modulus operation.
  366. UserTalk employs automatic type coercion when evaluating arithmetic and comparative operations; the two expressions of the modulus operation need not be of the same type. Generally, the resulting type is the more complex type, the one that can most readily represent both values.
  367. See Also    +
  368. *
  369. /
  370.  
  371. Verb    break
  372. Syntax    break
  373. Action    Terminates the innermost for, loop, fileloop, or while statement in which it is contained. Script execution continues at the next statement following the looping construct, skipping any subsequent statements within the current loop body.
  374. Examples    fileloop (fName in folderPath)
  375.     if file.isLocked (fName)
  376.         lockedFileFound = true
  377.         break
  378.     ++numberOfFiles
  379. if lockedFileFound
  380.     msg ("Found a locked file.")
  381. This is just a script fragment, so don’t attempt to execute it. A loop like the one above might be used to count the number of files in a folder about to be deleted, so that a confirmation dialog could be presented to the user. However, since a locked file was found, the folder cannot be deleted, and the loop is terminated early.
  382.  
  383. loop
  384.     if not dialog.ask ("What number am I thinking of?", @x)
  385.         return (false)
  386.     if x == 16396
  387.         break
  388.     msg ("Try again!")
  389. This is just a script fragment, so don’t attempt to execute it. This loop prompts the user for a number forever, until he or she exhibits astonishing clairvoyance or gets sick of the game. The break statement allows the loop to be terminated if the user gets lucky.
  390. Notes    The break statement only terminates the loop that contains it; loops outside of the innermost loop continue to execute as usual.
  391. See Also    for
  392. for
  393. fileloop
  394. loop
  395. while
  396. continue
  397.  
  398. Verb    bundle
  399. Syntax    bundle
  400.     statements
  401. Action    Executes statements once.
  402. Examples    bundle «set up the object database for a new run
  403.     app.clearNetworkApp ()
  404.     Frontier.pathstring = file.getPath ()
  405.     menu.currentsuite = ""
  406.     modes.currentmenu = 0
  407. Type this script into a script window. In this example, a fragment of Frontier’s standard startup script, the bundle statement serves purely as an encapsulation mechanism. The four statements in the bundle are executed exactly as if they appeared in line, outside of the bundle. The bundle statement provides additional structure to the script so that the statements can be expanded and collapsed together, and have a single comment that describes their combined action.
  408.  
  409. bundle «make sure the user has a notepad outline
  410.     local (notepad = @peopletable^.notepad)
  411.     if not defined (notepad^)
  412.         new (outlineType, notepad)
  413. Type this script into a script window. This example, taken from Frontier’s “user.login” script, illustrates an additional encapsulation property of the bundle statement. By declaring the “notepad” local variable within the bundle, its scope is only over those statements that actually work with it. As in the first example, the bundle statement can be collapsed leaving just its comment visible.
  414. See Also    on
  415. local
  416.  
  417. Verb    case
  418. Syntax    case expression
  419.    expr1
  420.       statements1
  421.    expr2
  422.       statements2
  423.    exprN
  424.       statementsN
  425. else
  426.    statements
  427. Action    Evaluates the case expression, and then evaluates expressions 1 through N in succession until one of the resulting values matches that of the case expression. When a matching value is found, the corresponding statements are executed, and the case statement is exited.
  428. The else clause of the case statement is optional. If it is provided, and none of the expressions in the main case body match the case expression, the else statements are executed.
  429. Examples    case dialog.yesNoCancel ("Save changes before quitting?")
  430.     1
  431.         msg ("Your changes are being saved…")
  432.         fileMenu.save ()
  433.     2
  434.         msg ("Your changes are being discarded…")
  435.     3
  436.         msg ("Ok, we won’t quit")
  437.         return (false) «don’t continue process
  438. fileMenu.quit ()
  439. Type this script into a script window. In this example, dialog.yesNoCancel is known to return a result of 1, 2 or 3. The case statement allows the appropriate action to be taken for each response.
  440.  
  441. case user.initials
  442.     "DW"
  443.         msg ("Hi Dave!")
  444.     "dmb"
  445.         msg ("Yo Doug!")
  446. else
  447.         msg ("Howdy stranger.")
  448. Type this script into a script window. This example demonstrates the use of the else clause, and also illustrates a feature of the case statement that is unlike most other languages: the case expression, and the body expressions, can work with values of any type.
  449. Notes    The body expressions do not have to be simple constants; they may be complex expressions if desired.
  450. Once an expression’s value matches that of the case expression, none of the subsequent expression are evaluated.
  451. See Also    if
  452.  
  453. Verb    continue
  454. Syntax    continue
  455. Action    Skips the remaining statements in the body of the current for, loop, fileloop, or while statement. Script execution continues with the next iteration of the looping construct, after incrementing the counter (in a for statement), executing the loop iteration expression (in a loop statement), or assigning the next file (in a fileloop statement).
  456. Example    fileloop (fName in folderPath)
  457.     if file.isFolder (fName) «skip folders
  458.         continue
  459.     if file.isLocked (fName)
  460.         ...
  461.     if file.size (fName) > 20000
  462.         ...
  463. (This is a script fragment; do not try to execute it in the Quick Script Window.) In this example, the use of the continue statement avoids having to indent the remainder of the loop body under an if statement. Typically, the continue statement will be used when there is more complex logic involved.
  464. See Also    for
  465. fileloop
  466. loop
  467. while
  468. break
  469.  
  470. Verb    fileloop
  471. Syntax    fileloop (identifier in expression)
  472.     statements
  473. Action    Evaluates expression as a string, to be interpreted as a file system path to a folder.
  474.  
  475. For each file in the folder indicated by expression, fileloop does the following:
  476. 1. assigns the full path of the file to identifier
  477. 2. executes statements
  478. Example    fileloop (fName in file.getSystemFolderPath ())
  479.      {msg (file.fileFromPath (fName));
  480.     clock.waitSixtieths (30)}
  481. Posts the name of each item in the System Folder to the Main Window, pausing a half-second between each one.
  482. Notes    If expression does not specify a valid path to an existing folder, the body statements will not be executed, and an error will be generated.
  483. If expression is the empty string, the fileloop will iterate over all mounted disk volumes.
  484. See Also    break
  485. continue
  486.  
  487. Verb    for
  488. Syntax    for identifier = expression1 to expression2
  489.        statements
  490. Action    Evaluates expression1 and expression2 as numeric values.
  491. Assigns the result of expression1 to identifier.
  492. As long as the value of identifier is less than or equal to the result of expression2, for ... to does the following:  executes statements and adds 1 to the value of identifier.
  493. Examples    for i = 1 to sizeOf (root){
  494.     msg (nameOf (root [i]));
  495.     clock.waitSixtieths (30)}
  496. It posts the name of each item in the root table to the Main Window, pausing a half-second between each one.
  497.  
  498. for i = 3 to 2
  499.     {msg ("This statement will not be executed")}
  500. Notes    If the result of expression1 is greater than that of expression2, the loop body will not be executed even once.
  501. The action of the for statement is almost identical to the following loop statement:
  502.     loop (identifier = expression1; identifier <= expression2; ++identifier)
  503.     statements
  504. However in the for statement, the expressions are always evaluated as numbers, and expression2 is evaluated once before entering the loop, rather than for each iteration. This gives the for statement a substantial performance advantage.
  505. See Also    loop
  506. while
  507. break
  508. continue
  509.  
  510. Verb    if
  511. Syntax    if expression
  512.     statements1
  513. else
  514.     statements2
  515. Action    Evaluates the if expression. If the result is true, executes statements1.
  516. The else clause of the if statement is optional. If it is provided, and expression evaluates to false, statements2 are executed.
  517. Examples    if not file.exists (path)
  518. {file.new (path);
  519. file.setType (path, 'TEXT')}
  520. In this simple form of the if statement, we only want to execute the statements that create a new text file if the file doesn’t already exist. If the call to file.exists returns true, the expression not file.exists (path) will evaluate to false, and the indented statements will not be executed.
  521.  
  522. if file.isFolder (path){
  523.     size = file.bytesInFolder (path)}
  524. else{
  525.     size = file.size (path)}
  526. This example demonstrates the use of the else clause, which enables us to take one of two possible courses of action depending on the result of a test — in this case whether we are dealing with a file or a folder.
  527. See Also    case
  528.  
  529. Verb    kernel
  530. Syntax    kernel (identifier)
  531. Action    Invokes a function built into Frontier’s kernel, one that is implemented in the program code rather than in scripts. The parameters to the script enclosing the kernel statement are passed on to the kernel function.
  532. Example    on exists (path)
  533.     kernel (file.exists)
  534. Calls to the “exists” script invoke the kernel function file.exists with the path parameter provided.
  535. Notes    Syntactically, the kernel call must be the only statement in the body of a script.
  536. The kernel statement is intended primarily for creators of Frontier verb scripts (i.e., UserLand Software), and is not generally applicable to script writing. Its purpose is to allow verb scripts whose names match that of their kernel function to be called with no loss of performance.
  537.  
  538. Verb    local
  539. Syntax    local
  540.    identifier1 [ = expression1]
  541.    identifier2 [ = expression2]
  542.    ...
  543.    identifierN [ = expressionN]
  544. or
  545. local (identifier1 [ = expression1], ..., identifierN [ = expressionN])
  546. Action    Creates local variables named identifier1 through identifierN, assigning the initial values that are the result of evaluating expressions 1 through N where provided.
  547. Evaluates each expression provided, assigning the result to the corresponding variable as its initial value.
  548. The scope of the variables is limited to the statements following the local statement, in the same block of code. That is, the definition does not persist past the last statement in the current if, while, loop, for, fileloop, on, bundle, case, or else statement body.
  549. Example    local (x = 1)
  550. if file.isFolder (path)
  551.     local (x)
  552.     x = file.byteInFolder (path) « this "x" is private
  553.     msg (string.kBytes (x))
  554. else
  555.     local (x = file.size (path)) « this "x" is private
  556.     msg (string.kBytes (x))
  557. msg (x) « "x" from first line is still 1
  558. (Do not attempt to execute this script outside a script window.) This example, while not recommended programming style, illustrates how the scope of a local variable is limited to the statements following it in the current body of the containing structural statement.
  559. Notes    The local statement does not have to appear as the first statement in a block of code. If it appears in the middle of a block, its scope excludes the statements that appear above it.
  560. UserTalk is a “dynamically scoped” language. That means that local variables can be “seen” by scripts called from a statement in the statement block. It is generally bad programming practice to use this language feature, but advanced script writers may find special circumstances where it may simplify an implementation.
  561. See Also    =
  562.  
  563. Verb    loop
  564. Syntax    loop
  565.     statements
  566. or
  567. loop (expression1; expression2; expression3)
  568.     statements
  569. Action    In its simplest form, where the three loop expressions are not provided, the loop statement executes its body statements repeatedly, forever. Such a loop can be terminated by a break or return statement in its body, or by the user canceling the script.
  570. In its more complex form, the loop statement is executed as follows:
  571. 1. expression1 is executed;
  572. 2. expression2 is evaluated;
  573. 3. as long as expression2 evaluates to true,
  574. 4. the body statements are executed;
  575. 5. expression3 is executed;
  576. 6. expression2 is re-evaluated.
  577. Examples    loop (wName = window.frontmost (); wName != "";  
  578. wName = window.next (wName)){msg (wName)}
  579. This loop iterates through all open windows, posting a message with their titles in the Main Window.
  580.  
  581. loop
  582.     if mouse.button () « user pressed the mouse
  583.         break
  584.     msg ("It's" + clock.now () + "you still haven’t clicked the mouse!")
  585. This loops until the user presses the mouse button, while posting a message of impatience.
  586. Notes    The complex loop form is most appropriate when the three expressions work together to control the loop iterations, as in the first example above.
  587. expression1 is executed only once; expression3 is executed after is iteration over the loop body.
  588. If expression2 initially evaluates to false, the loop body (and expression3) will not be executed even once.
  589. The action of the complex loop statement is almost identical to the following while statement:
  590.     expression1
  591.     while expression2
  592.         statements
  593.         expression3
  594. However, a continue statement in the while body would not cause expression3 to be executed before the next loop iteration, as it does with the loop statement.
  595. For simple counting loops, the for loop construct is simpler and more efficient.
  596. See Also    for
  597. while
  598. break
  599. continue
  600.  
  601. Verb    on
  602. Syntax    on identifier (idparam1, idparam2, ..., idparamN)
  603.     statements
  604. Action    Defines a local script named identifier, with parameters idParam1 through idParamN. The body statements are not executed; that occurs only when the script is invoked with a function call, consisting of identifier followed by a list of parameters enclosed in parentheses.
  605. Examples    on countWindows ()
  606.     return (appleEvent (app.id, 'app1', 'twin'))
  607. Type this script into a script window. This is the script for app.countWindows in Frontier.root. In this case, the local script countWindows takes no parameters, and its body is the single return statement that returns the result of an appleEvent call. Since the entire script consists of a local script definition, running the script will do nothing but define the script; there is no call to countWindows to cause its body statements to be executed. Scripts like these are intended to be called externally, by other scripts. A script that wishes to execute countWindows must name its database cell in a function call, as in numOfWindows = app.countWindows ().
  608.  
  609. on lockFiles (folder)
  610.     local (fName)
  611.     fileloop (fName in folder)
  612.         file.lock (fName)
  613. lockFiles ("HD80:folder1")
  614. lockFiles ("HD80:folder2")
  615. Type this script into a script window. This example demonstrates the use of a local script to allow a specialized bit of functionality — in this case locking all of the files in a folder — to be reused within a script. The on statement defines the “lockFiles” local script, which takes a single parameter that is expected to be the path of a folder. Below the script definition are two calls to the script, passing two different folders to be operated on.
  616. Notes    The number of parameters defined in the on statement is strict; all calls to the script must provide exactly that number. If the script does not take any parameters, an empty parameter list — () — must be provided in both its definition and any calls to it.
  617. The scope of a script defined with the on statement is generally the same as that of local variables, lasting the rest of the program statement block that contains it. However, if the script is the first local script in a program, and its name matches that of the script database cell that contains it, then scripts elsewhere in the database can call it by naming the database cell (and providing the appropriate parameter list).
  618. The on statement’s parameter list defines the local script’s name and the name of each parameter it requires. There is no specification made of what type of values are expected for each parameter, and thus there is no type validity checking when the script is called. If a parameter is provided whose type is inappropriate for a statement in the script body, an error will occur when executing that statement.
  619. If a script is intended to be callable from other scripts, it is important that its name match that of the database cell containing it. If the name does not match, the script will be assumed to be local to the implementation of the database script. The on statement will be executed as a definition, with the expectation that a call to it will appear subsequently in the body of the database script.
  620. See Also    bundle
  621. local
  622. return
  623.  
  624. Verb    return
  625. Syntax    return (expression)
  626. Action    Evaluates expression and exits the current script, with the result of expression being the value of the call that invoked it.
  627. Example    on exponentiate (n, power)
  628.     local (i, exp = 1)
  629.     for i = 1 to power
  630.         exp = exp * n
  631.     return (exp)
  632. result = exponentiate (10, 3)
  633. Type this script into a script window. In the last line of “exponentiate”, the local variable “exp” is the expression whose value is returned by the script. In the assignment statement below, the call exponentiate (10, 3) evaluates to 1000 — the value of “exp” when it is used in the return statement. Thus, the value 1000 is assigned to “result.”
  634. Notes    While the parentheses around the expression being returned are not required, we recommend their use for improved readability. This is a matter of scripting style and has no effect on the statement’s execution.
  635. See Also    on
  636.  
  637. Verb    while
  638. Syntax    while expression
  639.     statements
  640. Action    Evaluates expression. As long as it evaluates to true, the loop statements are executed, and expression is re-evaluated.
  641. Examples    while scratchpad.x < 0
  642.     if not dialog.getInt ("Enter a positive number:", @scratchpad.x)
  643.         return (false)
  644. This loop repeats until the user enters a positive value for scratchpad.x or cancels the dialog. Note that the dialog will never be presented if scratchpad.x is already greater than zero.
  645.  
  646. while window.frontmost () != ""
  647.     window.hide (window.frontmost ())
  648. This loop hides all of the open windows, including the Main Window.
  649. Notes    If expression initially evaluates to false, the loop body will not be executed even once.
  650. See Also    for
  651. loop
  652. break
  653. continue